<?xml version='1.0' encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

	<xsl:template match="Form" mode="system">
		<xsl:variable name="toPage">
			<xsl:choose>
				<xsl:when test="@Page">
					<xsl:value-of select="@Page"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$Page"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<form id="{@ID}" name="{@Name}" action="{$Self}/{$toPage}/{@Action}" method="{@Method}">
			<xsl:copy-of select="@*[ not(name() = 'ID') and not(name() = 'Name') and not(name() = 'Method') and not(name() = 'Page') and not(name() = 'Action') ]" />
			<xsl:if test="//Field/File">
 				<xsl:attribute name="enctype">multipart/form-data</xsl:attribute>
			</xsl:if>
			<xsl:if test="@onsubmit">
				<xsl:attribute name="onsubmit"><xsl:value-of select="@onsubmit"/></xsl:attribute>
			</xsl:if>
			<xsl:if test="@onkeypress">
				<xsl:attribute name="onkeypress"><xsl:value-of select="@onkeypress"/></xsl:attribute>
			</xsl:if>
			<div class="Form">
				<xsl:apply-templates/>
			</div>
		</form>
	</xsl:template>

	<xsl:template match="FormSection">
		<fieldset>
			<xsl:copy-of select="@*[ not(name() = 'Group') ]"/>
			<xsl:if test="@Group">
				<xsl:attribute name="class"><xsl:value-of select="@Group"/></xsl:attribute>
			</xsl:if>
			<xsl:apply-templates select="Legend"/>
			<xsl:apply-templates select="Description"/>
			<ol>
				<xsl:apply-templates select="*[ not(name()='Legend') and not(name()='Description') ]"/>
			</ol>
		</fieldset>
	</xsl:template>

	<xsl:template match="Legend">
		<legend><xsl:value-of select="."/></legend>
	</xsl:template>

	<!-- default Field match -->
	<xsl:template match="Field">
		<li>
			<xsl:if test="@Required = '1'">
				<xsl:attribute name="class">Required</xsl:attribute>
			</xsl:if>
			<xsl:if test="Field/*">
				<xsl:attribute name="style">float: left;</xsl:attribute>
			</xsl:if>
			<xsl:if test="string-length(Label) &gt; 0">
				<label><xsl:value-of select="Label"/></label>
			</xsl:if>
			<input name="{Name}">
				<xsl:copy-of select="@*[ not(name() = 'Required') ]"/>
				<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
					<xsl:attribute name="id">
						<xsl:call-template name="generate-id">
							<xsl:with-param name="text" select="Name"/>
						</xsl:call-template>
					</xsl:attribute>
				</xsl:if>
				<xsl:if test="not(@type)">
					<xsl:attribute name="type">text</xsl:attribute>
				</xsl:if>
				<xsl:attribute name="value">
					<xsl:call-template name="field-value">
						<xsl:with-param name="FieldName" select="Name"/>
						<xsl:with-param name="FieldValue" select="Value"/>
					</xsl:call-template>
				</xsl:attribute>
			</input>
			<!-- if we have a description, show it -->
			<xsl:if test="Description">
				<div class="Info">
					<xsl:apply-templates select="Description"/>
				</div>
			</xsl:if>
			<xsl:if test="Field">
				<xsl:apply-templates select="Field"/>
			</xsl:if>
			<!-- apply Content -->
			<xsl:apply-templates select="Content"/>
		</li>
	</xsl:template>

	<xsl:template match="Field[ FieldOptions ]">
		<li>
			<xsl:if test="@Required = '1'">
				<xsl:attribute name="class">Required</xsl:attribute>
			</xsl:if>
			<!-- if we have a field to embed or we are embedded -->
			<xsl:if test="Field/* and ../Field">
				<xsl:attribute name="style">float: left;</xsl:attribute>
			</xsl:if>
			<xsl:if test="string-length(Label) &gt; 0">
				<label><xsl:value-of select="Label"/></label>
			</xsl:if>
			<xsl:choose>
				<xsl:when test="FieldOptions/@As = 'checkbox' or FieldOptions/@As = 'radio'">
					<xsl:apply-templates select="FieldOptions">
						<xsl:with-param name="FieldValue">
							<xsl:call-template name="field-value">
								<xsl:with-param name="FieldName" select="Name"/>
								<xsl:with-param name="FieldValue" select="Value"/>
							</xsl:call-template>
						</xsl:with-param>
						<xsl:with-param name="FieldName" select="Name"/>
					</xsl:apply-templates>
				</xsl:when>
				<xsl:otherwise>
					<select name="{Name}" style="display: inline-block;">
						<xsl:copy-of select="@*[ not(name() = 'Required') ]"/>
						<xsl:copy-of select="FieldOptions/@*[ not(name() = 'As') ]"/>
						<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
							<xsl:attribute name="id">
								<xsl:call-template name="generate-id">
									<xsl:with-param name="text" select="Name"/>
								</xsl:call-template>
							</xsl:attribute>
						</xsl:if>
						<xsl:for-each select="Params/*">
							<xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute>
						</xsl:for-each>
						<xsl:apply-templates select="FieldOptions">
							<!-- get the selected value by calling field-value -->
							<xsl:with-param name="SelectedVal">
								<xsl:call-template name="field-value">
									<xsl:with-param name="FieldName" select="Name"/>
									<xsl:with-param name="FieldValue" select="Value"/>
								</xsl:call-template>
							</xsl:with-param>
						</xsl:apply-templates>
					</select>
				</xsl:otherwise>
			</xsl:choose>
			<!-- if we have a description, show it -->
			<xsl:if test="Description">
				<div class="Info">
					<xsl:apply-templates select="Description"/>
				</div>
			</xsl:if>
			<xsl:if test="Field">
				<xsl:apply-templates select="Field"/>
			</xsl:if>
			<!-- apply Content -->
			<xsl:apply-templates select="Content"/>
		</li>
	</xsl:template>

	<xsl:template match="Field[ @Type = 'textarea' ]">
		<li>
			<xsl:if test="@Required = '1'">
				<xsl:attribute name="class">Required</xsl:attribute>
			</xsl:if>
			<xsl:if test="Field/*">
				<xsl:attribute name="style">float: left;</xsl:attribute>
			</xsl:if>
			<xsl:if test="string-length(Label) &gt; 0">
				<label for="{Name}"><xsl:value-of select="Label"/></label>
			</xsl:if>
			<textarea name="{Name}">
				<xsl:copy-of select="@*[ not(name() = 'Required') ]"/>
				<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
					<xsl:attribute name="id">
						<xsl:call-template name="generate-id">
							<xsl:with-param name="text" select="Name"/>
						</xsl:call-template>
					</xsl:attribute>
				</xsl:if>
				<xsl:for-each select="Params/*">
					<xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute>
				</xsl:for-each>
				<xsl:call-template name="field-value">
					<xsl:with-param name="FieldName" select="Name"/>
					<xsl:with-param name="FieldValue" select="Value"/>
				</xsl:call-template>
			</textarea>
			<!-- if we have a description, show it -->
			<xsl:if test="string-length(Description) &gt; 0">
				<div class="Info">
					<xsl:value-of select="Description"/>
				</div>
			</xsl:if>
			<xsl:if test="Field">
				<xsl:apply-templates select="Field"/>
			</xsl:if>
			<!-- apply Content -->
			<xsl:apply-templates select="Content"/>
		</li>
	</xsl:template>

	<xsl:template match="Field[ @Type = 'hidden' ]">
		<input type="hidden" name="{Name}">
			<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
				<xsl:attribute name="id">
					<xsl:call-template name="generate-id">
						<xsl:with-param name="text" select="Name"/>
					</xsl:call-template>
				</xsl:attribute>
			</xsl:if>
			<xsl:attribute name="value">
				<xsl:call-template name="field-value">
					<xsl:with-param name="FieldName" select="Name"/>
					<xsl:with-param name="FieldValue" select="Value"/>
				</xsl:call-template>
			</xsl:attribute>
		</input>
	</xsl:template>

	<!-- this is used to add standard field html in order to have it turn out the same height as any other field -->
	<xsl:template match="Field[ @Type = 'blank' ]">
		<li style="visibility: hidden;">
			<label>&#160;</label>
			<input type="text"/>
		</li>
	</xsl:template>

	<xsl:template match="Button">
		<input type="button" value="{Value}" style="float: none;">
			<xsl:attribute name="value">
				<xsl:choose>
					<xsl:when test="Value"><xsl:value-of select="Value"/></xsl:when>
					<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
				</xsl:choose>
			</xsl:attribute>
			<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
				<xsl:attribute name="id">
					<xsl:call-template name="generate-id">
						<xsl:with-param name="text" select="Name"/>
					</xsl:call-template>
				</xsl:attribute>
			</xsl:if>
			<xsl:for-each select="Params/*">
				<xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute>
			</xsl:for-each>
		</input>
	</xsl:template>

	<!-- default FieldOptions template...called when no As attribute is specified -->
	<xsl:template match="FieldOptions | FieldOptions[ @As = 'select' ]">
		<xsl:param name="SelectedVal" select="''"/>
		<xsl:choose>
			<!-- if we have a source, read options from the source file -->
			<xsl:when test="@Source">
				<xsl:variable name="list" select="document(concat($Layout/Server/Root,@Source))/*"/>
				<xsl:if test="count($list) = 0">
					<xsl:message terminate="no">
						<option>We were unable to locate the requested file: <xsl:value-of select="concat($Layout/Server/Root,@Source)"/></option>
					</xsl:message>
				</xsl:if>
				<!-- factor in the default item which may be present in the source file -->
				<xsl:variable name="FinalSelection">
					<xsl:choose>
						<xsl:when test="string-length($SelectedVal) = 0">
							<!-- look for various nodes or attributes in which the value might be kept -->
							<xsl:value-of select="$list/*[ @default = '1' ]/Value | $list/*[ @default = '1' ]/@value | $list/*[ @default = '1' ]/@code | $list/*[ @default = '1' ]/@id"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$SelectedVal"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>
				<xsl:call-template name="select-options">
					<xsl:with-param name="list" select="$list"/>
					<xsl:with-param name="selectedval" select="$FinalSelection"/>
					<xsl:with-param name="recurse" select="@Recursive"/>
				</xsl:call-template>
				<!--
				<xsl:for-each select="$List/*[ @value | @code | @id | Value ]">
					<option value="{@value | @code | @id | Value}">
						<xsl:if test="(@value | @code | @id | Value) = $FinalSelection">
							<xsl:attribute name="selected">true</xsl:attribute>
						</xsl:if>
						<xsl:value-of select="Label | @label"/>
					</option>
				</xsl:for-each>
				-->
			</xsl:when>
			<!-- otherwise, loop thru in-context options -->
			<xsl:when test="count(*)">
				<xsl:variable name="FinalSelection">
					<xsl:choose>
						<xsl:when test="string-length($SelectedVal) = 0">
							<xsl:value-of select="*[ @default = '1' ]/Value | *[ @default = '1' ]/@value | *[ @default = '1' ]/@code | *[ @default = '1' ]/@id"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$SelectedVal"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>
				<xsl:call-template name="select-options">
					<xsl:with-param name="list" select="."/>
					<xsl:with-param name="selectedval" select="$FinalSelection"/>
				</xsl:call-template>
				<!--
				<xsl:for-each select="*[ @value | @code | @id | Value ]">
					<option value="{@value | @code | @id | Value}">
						<xsl:if test="(@value | @code | @id | Value) = $FinalSelection">
							<xsl:attribute name="selected">true</xsl:attribute>
						</xsl:if>
						<xsl:value-of select="Label | @label"/>
					</option>
				</xsl:for-each>
				-->
			</xsl:when>
			<xsl:otherwise>
				<option>No options, and no source in match=FieldOptions</option>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template name="select-options">
		<xsl:param name="list" select="''"/>
		<xsl:param name="selectedval" select="''"/>
		<xsl:param name="recurse" select="''"/>
		<!-- loop thru each item which has a value, either in attributes or nodes -->
		<xsl:for-each select="$list/*[ @value | @code | @id | Value ]">
			<xsl:choose>
				<xsl:when test="count(*) and not($recurse = '0')">
					<option value="{@value | @code | @id | Value}">
						<xsl:copy-of select="@*"/>
						<xsl:if test="(@value | @code | @id | Value) = $selectedval">
							<xsl:attribute name="selected">true</xsl:attribute>
						</xsl:if>
						<xsl:value-of select="Label | @label"/>
					</option>
					<xsl:call-template name="select-options">
						<xsl:with-param name="list" select="."/>
						<xsl:with-param name="selectedval" select="$selectedval"/>
					</xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<option value="{@value | @code | @id | Value}">
						<xsl:copy-of select="@*"/>
						<xsl:if test="(@value | @code | @id | Value) = $selectedval">
							<xsl:attribute name="selected">true</xsl:attribute>
						</xsl:if>
						<xsl:value-of select="Label | @label"/>
					</option>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each>
	</xsl:template>

	<xsl:template match="FieldOptions[ @As = 'checkbox' ] | FieldOptions[ @As = 'radio' ]">
		<xsl:param name="SelectedVal" select="''"/>
		<xsl:param name="FieldName" select="''"/>
		<xsl:for-each select="*">
			<p>
				<xsl:variable name="inputid">
					<xsl:choose>
						<xsl:when test="string-length(@id) = 0 and string-length(@ID) = 0">
							<xsl:call-template name="generate-id">
								<xsl:with-param name="text" select="$FieldName"/>
							</xsl:call-template>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="@id | @ID"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>
				<input type="{../@As}" value="{$SelectedVal}">
					<xsl:copy-of select="@*[ not(name() = 'name') and not(name() = 'label') ]"/>
					<xsl:if test="string-length(@id) = 0 and string-length(@ID) = 0">
						<xsl:attribute name="id"><xsl:value-of select="$inputid"/></xsl:attribute>
					</xsl:if>
					<xsl:if test="string-length($FieldName) &gt; 0">
						<xsl:attribute name="name"><xsl:value-of select="$FieldName"/></xsl:attribute>
					</xsl:if>
				</input>
				<label for="{$inputid}" style="display: inline;">
					<xsl:value-of select="Label | @label"/>
				</label>
			</p>
		</xsl:for-each>
	</xsl:template>

	<!--
	Returns the value of the supplied field name by looking first in the full request, then the flattened request, then the FormData block (if it's there).
	If it can't find anything, it returns the supplied value, falling back to a zero-length string.
	-->
	<xsl:template name="field-value">
		<xsl:param name="FieldName"/>
		<xsl:param name="FieldValue" select="''"/>
		<xsl:choose>
			<!-- check in the Full request -->
			<xsl:when test="string-length($Request/Full/*[ name() = $FieldName ]) &gt; 0">
				<xsl:value-of select="$Request/Full/*[ name() = $FieldName ]"/>
			</xsl:when>
			<!-- check in the Flattened request -->
			<xsl:when test="string-length($Request/Flat/*[ @Name = $FieldName ]) &gt; 0">
				<xsl:value-of select="$Request/Flat/*[ @Name = $FieldName ]"/>
			</xsl:when>
			<!-- check in FormData -->
			<xsl:when test="string-length(//FormData/*[ @Name = $FieldName ]) &gt; 0">
				<xsl:value-of select="//FormData/*[ @Name = $FieldName ]"/>
			</xsl:when>
			<!-- default to whatever is in the field -->
			<xsl:otherwise>
				<xsl:value-of select="$FieldValue"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<!--
	Finds all <Field> nodes and returns a new node for each containing the value of the <Name> node.
	Includes the <Value> node also for defaulting purposes.
	This is used to inject field values into the gxpage-runtime node for use by the Forms.xsl stylesheet.
	-->
	<xsl:template match="FormData">
		<xsl:variable name="filedata" select="document(@File)"/>
		<Fields>
			<xsl:for-each select="$filedata//descendant-or-self::Field">
				<Field>
					<Name><xsl:value-of select="Name"/></Name>
					<Value><xsl:value-of select="Value"/></Value>
				</Field>
			</xsl:for-each>
		</Fields>
	</xsl:template>

	<!--
	Strips all funky characters from the provided text and returns a value suitable for use as an @id.
	-->
	<xsl:template name="generate-id">
		<xsl:param name="text" select="''"/>
		<xsl:value-of select="translate($text,'[]()# ,','_______')"/>
	</xsl:template>

</xsl:stylesheet>
